import { XYZ_CONFIG, PLAYERINFO_CONFIG } from "../config.js";

class XyzDataClass {
    constructor (type){
        this.XYZ_CONFIG = XYZ_CONFIG;
        this.type = type;
    }
    /**
     * @description: 获取坐标数据对象
     * @param {string|undefined} xuid
     * @return {object}
     */    
    #getData(xuid){
        let xyzData;
        switch (this.type){
            case 'public':
                xyzData = this.XYZ_CONFIG.get('public');break;
            case 'person':
                xyzData = this.XYZ_CONFIG.get('person')[xuid];break;
            default:
                xyzData = null;break;
        }
        return xyzData;
    }
    /**
     * @description: 保存坐标数据
     * @param {object} xyzData 被保存的坐标数据
     * @param {string|undefined} xuid 玩家xuid
     * @return {boolean}
     */    
    #saveData(xyzData, xuid){
        let res;
        switch (this.type){
            case 'public':
                res = this.XYZ_CONFIG.set('public', xyzData);break;
            case 'person':{
                let tempData = this.XYZ_CONFIG.get('person');
                tempData[xuid] = xyzData;
                res = this.XYZ_CONFIG.set('person', tempData);break;
            }
            default:
                res = null;break;
        }
        return res;
    }

    /**
     * @description: 初始化数据
     * @param {string|undefined} xuid
     * @return {undefined}
     */    
    init(xuid){
        if (this.#getData(xuid) == null){
            this.#saveData({"默认": []}, xuid);
        }
    }
    /**
     * @description: 获取全部坐标数据
     * @param {string|undefined} xuid
     * @return {object}
     */    
    get(xuid){
        return this.#getData(xuid);
    }

    /**
     * @description: 获取坐标数量
     * @param {string|undefined} xuid
     * @return {number}
     */    
    count(xuid){
        return Object.values(this.#getData(xuid)).reduce((total, xyzList)=>total+xyzList.length,0);
    }

    /**
     * @description: 获取传送点数量
     * @param {string|undefined} xuid
     * @return {number}
     */    
    countTp(xuid){
        return Object.values(this.#getData(xuid)).reduce((total, xyzList)=>total + xyzList.filter(xyz=>xyz.tpAllow).length,0);
    }
    
    /**
     * @description: 添加坐标分类
     * @param {string} categoryName 分类名称
     * @param {string|undefined} xuid
     * @return {boolean}
     */    
    addCategory(categoryName, xuid){
        let xyzData = this.#getData(xuid);
        if (xyzData == null){return false;}
        if (xyzData[categoryName] != undefined){
            return false;
        }
        xyzData[categoryName] = [];
        return this.#saveData(xyzData, xuid);
    }

    /**
     * @description: 删除坐标分类
     * @param {string} categoryName 分类名称
     * @param {string|undefined} xuid
     * @return {boolean}
     */    
    removeCategory(categoryName, xuid){
        let xyzData = this.#getData(xuid);
        if (xyzData == null){return false;}
        delete xyzData[categoryName];
        return this.#saveData(xyzData, xuid);
    }

    /**
     * @description: 重命名坐标分类
     * @param {string} categoryName 分类名称
     * @param {string} newName 新名称
     * @param {string|undefined} xuid
     * @return {boolean}
     */ 
    renameCategory(categoryName, newName, xuid){
        let xyzData = this.#getData(xuid);
        if (xyzData == null){return false;}
        xyzData[newName] = JSON.parse(JSON.stringify(xyzData[categoryName]));
        delete xyzData[categoryName];
        return this.#saveData(xyzData, xuid);
    }

    /**
     * @description: 列出分类
     * @param {string} xuid
     * @return {Array} 
     */    
    listCategory(xuid){
        let xyzData = this.#getData(xuid);
        if (xyzData == null){return null;}
        return Object.keys(xyzData);
    }

    
    addPos(categoryName, warp, xuid){
        if (warp.name == undefined || warp.pos == undefined){return false;}
        let _warp;
        let playerInfo = PLAYERINFO_CONFIG.get('players')[xuid];
        if (playerInfo == null){return false;}
        switch (this.type){
            case 'public': // 公共坐标需记入记录者信息
                _warp = {
                    realName: playerInfo.realName,
                    uuid: playerInfo.uuid,
                    xuid: playerInfo.xuid,
                    time: new Date().getTime(),
                    tpAllow: false,
                    ...warp
                };
                break;
            case 'person':
                _warp = warp;
                break;
            default:
                _warp = warp;
                break;
        }

        let xyzData = this.#getData(xuid);
        if (xyzData[categoryName] == undefined){
            xyzData[categoryName] = [];
        }
        if (xyzData[categoryName].find(w=>w.name === _warp.name) != undefined){
            return false; // 重复name返回false;
        }
        xyzData[categoryName].push(_warp);
        return this.#saveData(xyzData, xuid);
    }

    removePos(categoryName, warpName, xuid){
        let xyzData = this.#getData(xuid);
        if (xyzData == null){return true;}
        let index = xyzData[categoryName]?.findIndex(w=>w.name === warpName);
        if (index == undefined || index == -1){return true;}
        xyzData[categoryName].splice(index, 1);
        return this.#saveData(xyzData, xuid);
    }

    listPos(categoryName, xuid){
        return this.#getData(xuid)[categoryName];
    }
}

export const XYZ_PUBLIC = new XyzDataClass('public');
export const XYZ_PERSON = new XyzDataClass('person');
